package es.udc.acs.consorcio.server;


import java.util.Formatter;

import es.udc.acs.consorcio.mensaje.ThreadMensaje;
import es.udc.acs.consorcio.sesion.GestorSesion;
import es.udc.acs.consorcio.sesion.Sesion;
import es.udc.acs.consorcio.ui.MainConsorcio;
import es.udc.acs.database.operations.DBConsorcioOperations;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.udp.QuestionServer;
import es.udc.acs.utils.CodigosFAP;
import es.udc.acs.utils.FormateadorControl;
import es.udc.acs.utils.GestorProperties;

public class ControlServer implements QuestionServer {

	@Override
	public String procesarPregunta(String pregunta) {
		String origen;
		String destino;
		String tipo;
		
		String response = CodigosFAP.CE_OTRAS_CAUSAS;
		
		origen  = ParserMensaje.obtenerOrigen(pregunta);
		destino = ParserMensaje.obtenerDestino(pregunta);
		tipo	= ParserMensaje.obtenerTipo(pregunta);
		
		if (!MainConsorcio.getDisponible()) {
			return destino + origen + CodigosFAP.NO_RESPUESTA;
		}
		
		GestorProperties.tratarMensaje(
				"ControlServer:mensaje recibido: ",pregunta);
		
		FormateadorControl.formatearMensaje(pregunta);	
		
		if(!CodigosFAP.esControl(tipo)){
			
			GestorProperties.tratarMensaje(
					"ControlServer:mensaje enviado: ",destino + origen + response);
			FormateadorControl.formatearMensaje(destino + origen + response);
			
			return destino + origen + response;
		}
		
		if (tipo.equals(CodigosFAP.CM_B_PC_ABRIR_SESION)){
			response = abrirSesion(origen, ParserMensaje.obtenerCuerpo(pregunta));			
		}else if(tipo.equals(CodigosFAP.CM_B_PC_DETENER_TRAFICO)){
			response = detenerTrafico(origen);
		}else if(tipo.equals(CodigosFAP.CM_B_PC_REANUDAR_TRAFICO)){
			response = reanudarTrafico(origen);
		}else if(tipo.equals(CodigosFAP.CM_B_PC_CIERRE_SESION)){
			response = cierreSesion(origen, ParserMensaje.obtenerCuerpo(pregunta));
		}
		
		mostrarEstadoSesion(origen);
		
		FormateadorControl.formatearMensaje(destino + origen + response);			
		GestorProperties.tratarMensaje(
				"ControlServer:mensaje enviado: ",destino + origen + response);

		return destino + origen + response;
	}


	private static void mostrarEstadoSesion(String idBanco) {
		String estado;
		try {
			estado = GestorSesion.getSesion(idBanco).obtenerEstado();

		} catch (Exception e) {
			estado = "cerrada";
		}
		System.out.println(">Estado sesion: "+estado);
	}
	
	
	private String abrirSesion(String idBanco, String cuerpo){
		int numCanales;
		String portHost;
		int port;
		String host;
		
		Sesion sesion;
		
		numCanales = Integer.parseInt(ParserMensaje.obtenerNumCanalesAS(cuerpo));
		portHost   = ParserMensaje.obtenerPuertoAS(cuerpo);
		
		host = portHost.substring(0,14);
		port = Integer.parseInt(portHost.substring(16));
		GestorProperties.tratarMensaje("APERTURA SESION <" + idBanco +">", cuerpo);
		sesion = new Sesion(idBanco,host, port, numCanales);
		try {			
			// si no se puede añadir es que existe alguna ya
			if(GestorSesion.addSesion(idBanco, sesion)){
				System.out.println("sesion añadida");
				
				// Si hay alguna anterior en la base de datos sustituimos
				if (DBConsorcioOperations.existeSesionConsorcio(idBanco)) {
					DBConsorcioOperations.guardarSesionConsorcio(idBanco, sesion);
				} else {
					DBConsorcioOperations.crearSesionConsorcio(idBanco, sesion);
				}
				/* Enviamos los mensajes offline */
				new ThreadMensaje(idBanco).start();				
				
			} else {
				// caso banco con inicio limpio y consorcio tiene una sesion
				System.out.println(
						"Sesion ya existente, se procede al reinicio");
				GestorSesion.removeSesion(idBanco);
				abrirSesion(idBanco, cuerpo);
			}
			
			return CodigosFAP.CM_C_RC_ABRIR_SESION + CodigosFAP.CODRE_CORRECTA
					+ CodigosFAP.CE_CORRECTO;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return CodigosFAP.CM_C_RC_ABRIR_SESION + CodigosFAP.CODRE_DENEGADA
				+ CodigosFAP.CE_SESION_YA_ABIERTA;
	}
	
	
	private String detenerTrafico(String idBanco){

		Sesion sesion;
		
		if ((sesion = GestorSesion.getSesion(idBanco)) != null) {
			
			if (sesion.detenerTrafico()) {
				return CodigosFAP.CM_C_RC_DETENER_TRAFICO + CodigosFAP.CODRE_CORRECTA
						+ CodigosFAP.CE_CORRECTO;
			}else {
				return CodigosFAP.CM_C_RC_DETENER_TRAFICO + CodigosFAP.CODRE_DENEGADA
						+ CodigosFAP.CE_TRAFICO_NO_DETENIDO;
			}
			
		} else {
			return CodigosFAP.CM_C_RC_DETENER_TRAFICO + CodigosFAP.CODRE_DENEGADA
					+ CodigosFAP.CE_NO_EXISTE_SESION;
		}

	}

	
	private String reanudarTrafico(String idBanco){
		
		Sesion sesion;
		
		if ((sesion = GestorSesion.getSesion(idBanco)) != null) {
			
			if (sesion.reanudarTrafico()) {
				new ThreadMensaje(idBanco).start();
				return CodigosFAP.CM_C_RC_REANUDAR_TRAFICO + CodigosFAP.CODRE_CORRECTA
						+ CodigosFAP.CE_CORRECTO;
			}else {
				return CodigosFAP.CM_C_RC_REANUDAR_TRAFICO + CodigosFAP.CODRE_DENEGADA
						+ CodigosFAP.CE_OTRAS_CAUSAS;
			}
			
		} else {
			return CodigosFAP.CM_C_RC_REANUDAR_TRAFICO + CodigosFAP.CODRE_DENEGADA
					+ CodigosFAP.CE_NO_EXISTE_SESION;
		}
	}
	
	
	private String cierreSesion(String idBanco,String cuerpo){

		Sesion sesion;
		
		if ((sesion = GestorSesion.getSesion(idBanco)) != null) {
			
			if (sesion.cierreSesion()) {
				
				if (!(Integer.parseInt(ParserMensaje.obtenerReintegrosCS(cuerpo,0)) 
						== (sesion.obtenerReintegros())) 
						|| !(Integer.parseInt(ParserMensaje.obtenerAbonosCS(cuerpo,0)) 
						== sesion.obtenerAbonos()) 		
						|| !(Integer.parseInt(ParserMensaje.obtenerTraspasosCS(cuerpo,0)) 
						== sesion.obtenerTraspasos())) {
							
						System.out.println("AVISO:Diferencias de conciliacion");				
					}
							
				return CodigosFAP.CM_C_RC_CIERRE_SESION + CodigosFAP.CODRE_CORRECTA
						+ CodigosFAP.CE_CORRECTO
						+formatearTotales(sesion.obtenerReintegros())
						+formatearTotales(sesion.obtenerAbonos())
						+formatearTotales(sesion.obtenerTraspasos());
			}else {
				return CodigosFAP.CM_C_RC_CIERRE_SESION + CodigosFAP.CODRE_DENEGADA
						+ CodigosFAP.CE_OTRAS_CAUSAS;
			}
			
		} else {
			return CodigosFAP.CM_C_RC_CIERRE_SESION + CodigosFAP.CODRE_DENEGADA
					+ CodigosFAP.CE_NO_EXISTE_SESION;
		}
	}
	
	
	private static String formatearTotales(int num){
		
		try {
	        Formatter fmt = new Formatter();
	        
	        fmt.format("%010d",num);
	        String res = fmt.toString();
	        
	        return res;
		} catch (Exception e) {
			return null;
		}		
	}

}
